(ns fxbattle.server.gameserver
 (:import
   (java.net Socket ServerSocket)
   (fxbattle.protos ClientProtos ClientProtos$RequestToPlay ClientProtos$SetPath))
 (:require fxbattle.server.core fxbattle.server.playercomms fxbattle.server.ai)
 (:gen-class))

;;;
(defn play-game 
  "Main game loop"
  [game]
  (try
    (println "Starting the Game")
    (reset! (:started game) true)
    (while (not (fxbattle.server.core/game-over? game))
      (fxbattle.server.core/do-update game)
      (. Thread (sleep 250)))
    (finally
      (reset! (:started game) false)
      (println "Game Over")
      (println (:name (first (fxbattle.server.core/remaining-players game))) "wins!!!"))))

(defn setup
  "Initializes the game, spawns necessary threads and starts the game loop"
  ([] (setup 4321 5 5 2 0))
  ([port height width number-of-players number-of-ai]
    (let [game (fxbattle.server.core/make-game height width)]
      (try
        (fxbattle.server.playercomms/listen-for-players port number-of-players game)
        (dotimes [count number-of-ai]
          (println "Start Computer Player" (inc count))
          (fxbattle.server.ai/run-computer-player (format "Computer %d" (inc count)) game))
        (play-game game)
        (finally
          (println "Stop AI")
          (fxbattle.server.ai/stop-computer-players))))))

;;;
(defn -main 
  "FxBattle core game server main loop"
  [& args]
  (.start
    (Thread.
      (fn []
        (let [*generation-rate* (Integer/parseInt (nth args 5))]
          (setup
            (Integer/parseInt (nth args 0))
            (Integer/parseInt (nth args 1))
            (Integer/parseInt (nth args 2))
            (Integer/parseInt (nth args 3))
            (Integer/parseInt (nth args 4))))))))


